package com.ccteam.fluidmusic.ui.album

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.doOnPreDraw
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.paging.LoadState
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.GridLayoutManager
import com.ccteam.fluidmusic.NavAlbumDirections
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentNewAlbumBinding
import com.ccteam.fluidmusic.utils.TransitionUtils
import com.ccteam.fluidmusic.view.adapters.AlbumListItemPagingAdapter
import com.ccteam.fluidmusic.view.adapters.paging.CustomLoadStateAdapter
import com.ccteam.fluidmusic.view.adapters.toolbar.ToolbarTitleAdapter
import com.ccteam.fluidmusic.view.base.LightBounceEdgeEffectFactory
import com.ccteam.fluidmusic.widget.AnimToolbarScrollListener
import com.ccteam.shared.result.album.AlbumListItem
import com.ccteam.shared.result.title.ToolbarTitleItem
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * 新专推荐界面Fragment
 */
@AndroidEntryPoint
class NewAlbumFragment : Fragment() {
    private var _binding: FragmentNewAlbumBinding? = null
    private val binding: FragmentNewAlbumBinding get() = _binding!!

    private val newAlbumViewModel by viewModels<NewAlbumViewModel>()

    @Inject lateinit var lightBounceEdgeEffectFactory: LightBounceEdgeEffectFactory

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentNewAlbumBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        exitTransition = TransitionUtils.exitScale
        reenterTransition = TransitionUtils.enterScale
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        postponeEnterTransition()
        view.doOnPreDraw {
            startPostponedEnterTransition()
        }

        val titleAdapter = ToolbarTitleAdapter()
        titleAdapter.submitList(mutableListOf(ToolbarTitleItem(getString(R.string.online_music_new_album))))
        val dataAdapter = AlbumListItemPagingAdapter(callback)

        binding.toolbarAlbumList.setNavigationOnClickListener {
            findNavController().navigateUp()
        }

        val concatAdapter = ConcatAdapter(titleAdapter,dataAdapter.withLoadStateFooter(
            CustomLoadStateAdapter(dataAdapter,true){
                dataAdapter.retry()
            }
        ))

        val spanSizeLookup = object: GridLayoutManager.SpanSizeLookup(){
            override fun getSpanSize(position: Int): Int {
                return if(position == 0 || position == concatAdapter.itemCount - 1){
                    2
                } else {
                    1
                }
            }

        }

        val layoutManager = GridLayoutManager(requireContext(),2)
        layoutManager.spanSizeLookup = spanSizeLookup
        // 设置成表格布局，每行最多2个
        binding.rvNewAlbum.layoutManager = layoutManager

        // 设置回弹效果
        lightBounceEdgeEffectFactory.applyBounceView(binding.rvNewAlbum,this)
        binding.rvNewAlbum.edgeEffectFactory = lightBounceEdgeEffectFactory
        binding.rvNewAlbum.addOnScrollListener(AnimToolbarScrollListener(binding.toolbarTitle))

        binding.rvNewAlbum.adapter = concatAdapter

        viewLifecycleOwner.lifecycleScope.launch {
            newAlbumViewModel.newAlbums.collectLatest {
                dataAdapter.submitData(it)
            }
        }

        viewLifecycleOwner.lifecycleScope.launch {
            dataAdapter.loadStateFlow.collectLatest { state ->
                binding.statusView.changeToLoadingStatus(state.refresh is LoadState.Loading)
                binding.statusView.changeToErrorStatus(state.refresh,
                    state.append.endOfPaginationReached && dataAdapter.itemCount < 1)
            }
        }

        binding.statusView.setRetryClickListener {
            dataAdapter.refresh()
        }

    }

    private val callback = object: com.ccteam.fluidmusic.view.adapters.AlbumListItemAdapter.AlbumListItemCallback{

        override fun onClickItem(view: View, albumItem: AlbumListItem) {
            val transitionName = getString(R.string.album_detail_transition_name)
            val extra = FragmentNavigatorExtras(view to transitionName)

            findNavController().navigate(
                NavAlbumDirections.actionGlobalAlbumDetailFragment(
                albumItem.albumId
            ),extra)
        }

    }

    override fun onDestroyView() {
        super.onDestroyView()

        binding.rvNewAlbum.clearOnScrollListeners()
        _binding = null
    }
}